// 导入日志宏（错误会写入文件）
use log::{error, warn, info, debug};
use crate::AppState;  // 根据项目实际路径调整 AppState 导入
use reqwest::{Client, Error as ReqwestError};
use std::sync::Arc;
use std::time::Duration;
// 导入 Tokio Broadcast Receiver（确保类型匹配）
use tokio::sync::broadcast::Receiver;

pub struct Worker {
    state: Arc<AppState>,
    http_client: Client,  // 复用 HTTP 客户端，提升性能
}

impl Worker {
    /// 创建 Web Hook Worker 实例
    pub fn new(state: Arc<AppState>) -> Self {
        // 初始化带超时的 HTTP 客户端
        let http_client = Client::builder()
            .timeout(Duration::from_secs(10))  // 10秒超时，避免阻塞
            .build()
            .expect("Web Hook HTTP 客户端初始化失败（请检查 reqwest 依赖）");

        // 记录初始化日志（输出到文件和控制台）
        match &state.web_hook {
            Some(url) => info!("Web Hook Worker 初始化完成，目标地址: {}", url),
            None => warn!("Web Hook Worker 初始化完成，但未配置目标地址（不会发送请求）"),
        }

        Worker {
            state,
            http_client,
        }
    }

    /// 启动 Worker，监听消息并发送 Web Hook 请求
    pub async fn serve(self) {
        // 关键修复：subscribe() 直接返回 Receiver（非 Result），无需 match 错误
        let mut rx: Receiver<String> = self.state.channel.subscribe();
        info!("Web Hook Worker 开始运行，等待消息触发...");

        // 循环监听消息通道
        while let Ok(msg) = rx.recv().await {
            // 检查是否配置 Web Hook 地址
            let Some(web_hook_url) = &self.state.web_hook else {
                debug!("Web Hook 未配置地址，跳过消息（长度: {} 字节）", msg.len());
                continue;
            };

            // 记录调试日志（仅写入文件，不刷屏控制台）
            debug!(
                "触发 Web Hook 请求：地址={}, 消息长度={} 字节",
                web_hook_url,
                msg.len()
            );

            // 发送 POST 请求并处理结果（错误日志写入文件）
            match self.http_client
                .post(web_hook_url)
                .header("Content-Type", "text/plain")  // 适配文本消息格式
                .body(msg.clone())  // 克隆消息体，便于错误日志预览
                .send()
                .await
            {
                // 请求发送成功（无论响应状态码）
                Ok(response) => {
                    let status = response.status();
                    if status.is_success() {
                        info!(
                            "Web Hook 请求成功：地址={}, 响应状态码={}",
                            web_hook_url, status
                        );
                    } else {
                        // 非 2xx 状态码，记录警告日志
                        warn!(
                            "Web Hook 响应异常：地址={}, 状态码={}, 消息预览={:?}",
                            web_hook_url,
                            status,
                            msg.chars().take(50).collect::<String>()  // 预览前50字符
                        );
                    }
                }

                // 请求发送失败（网络错误、超时等），记录错误日志（必写入文件）
                Err(e) => {
                    error!(
                        "Web Hook 请求失败：地址={}, 错误原因={:?}, 消息预览={:?}",
                        web_hook_url,
                        map_reqwest_error(&e),  // 解析错误类型，提升可读性
                        msg.chars().take(50).collect::<String>()
                    );
                }
            }
        }

        // 循环退出（通道被关闭），记录警告日志
        warn!("Web Hook Worker 消息监听循环退出（消息通道已关闭）");
    }
}

/// 辅助函数：解析 reqwest 错误类型，输出更易读的信息
fn map_reqwest_error(e: &ReqwestError) -> String {
    if e.is_timeout() {
        "请求超时（超过10秒）".to_string()
    } else if e.is_connect() {
        format!("连接失败：{}", e)
    } else if e.is_status() {
        format!("响应状态错误：{}", e)
    } else if e.is_body() {
        "请求体/响应体处理错误".to_string()
    } else {
        format!("未知 HTTP 错误：{}", e)
    }
}
